// EMERGENT GAME TECHNOLOGIES PROPRIETARY INFORMATION
//
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Emergent Game Technologies and may not
// be copied or disclosed except in accordance with the terms of that
// agreement.
//
//      Copyright (c) 1996-2008 Emergent Game Technologies.
//      All Rights Reserved.
//
// Emergent Game Technologies, Chapel Hill, North Carolina 27517
// http://www.emergent.net
//---------------------------------------------------------------------------
//  GnTAbstractPoolAllocator inline functions

//---------------------------------------------------------------------------
template <class T> inline
void GnTAbstractPoolAllocator<T>::EnsureFreeMem()
{
	if (!ms_pkFreeMem)
		CreateFreeMem();
}
//---------------------------------------------------------------------------
template <class T> inline
void GnTAbstractPoolAllocator<T>::CreateFreeMem()
{
	GnAssert(ms_pkFreeMem == 0);
	GnAssert(ms_uiBlockSize >= 2);

	ms_pkFreeMem = GnNew typename GnTAbstractPoolAllocator<T>::AllocNode[
		ms_uiBlockSize];

		// Handle end point
		typename GnTAbstractPoolAllocator<T>::AllocNode *pkCurr =
			ms_pkFreeMem + ms_uiBlockSize - 1;
		pkCurr->m_pkNext = 0;

		unsigned int i = 1;

		do
		{
			pkCurr = ms_pkFreeMem + i;
			pkCurr->m_pkNext = pkCurr + 1;
		} while(i++ < ms_uiBlockSize - 2);

		if (ms_pkBlockHeader)
		{
			// add block to head of list
			ms_pkFreeMem->m_pkNext = ms_pkBlockHeader;
			ms_pkBlockHeader = ms_pkFreeMem;
		}
		else
		{
			ms_pkBlockHeader = ms_pkFreeMem;
			ms_pkBlockHeader->m_pkNext = 0;
		}

		ms_pkFreeMem = ms_pkFreeMem + 1;
}
//---------------------------------------------------------------------------
template <class T> inline
void GnTAbstractPoolAllocator<T>::_SDMShutdown()
{
	typename GnTAbstractPoolAllocator<T>::AllocNode* pkCurr = ms_pkBlockHeader;

	while (pkCurr)
	{
		typename GnTAbstractPoolAllocator<T>::AllocNode* pkNext =
			pkCurr->m_pkNext;
		GnDelete [] pkCurr;
		pkCurr = pkNext;
	}

	ms_pkBlockHeader = NULL;
	ms_pkFreeMem = NULL;
}
//---------------------------------------------------------------------------
template <class T> inline
void GnTAbstractPoolAllocator<T>::SetBlockSize(unsigned int uiBlockSize)
{
	GnAssert(uiBlockSize >= 2);
	ms_uiBlockSize = uiBlockSize;
}
//---------------------------------------------------------------------------
